package com.etcn.common.utils.sms;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.etcn.common.config.SmsConfig;
import com.etcn.common.utils.DataUtil;
import com.etcn.common.utils.PubFun;
import com.etcn.common.utils.sms.constant.Constants;
import com.etcn.common.utils.sms.constant.ErrorConsts;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import com.etcn.common.redis.RedisService;
import com.etcn.common.utils.StringUtil;
import com.etcn.common.utils.XStreamUtil;
import ch.qos.logback.classic.Logger;


/**
 * 短信工具类
 *
 * @author guozc
 */
@Component
public class SmsUtil {

    private static Logger serviceLogger = (Logger) LoggerFactory.getLogger("service_file_log");

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisService redisService;

    @Autowired
    private SmsConfig smsConfig;

    private static ExecutorService service = Executors.newFixedThreadPool(5);


    /**
     * 发送短信
     *
     * @param mobile  手机号码
     * @param content 短信内容
     * @return
     * @throws Exception
     */
    public boolean send(String mobile, String content) throws Exception {
        // 参数校验
        if (StringUtil.isEmpty(mobile)) {
            PubFun.renderError(ErrorConsts.MOBILE_NOT_EMPTY);
        }
        if (StringUtil.isEmpty(content)) {
            PubFun.renderError(ErrorConsts.SMS_CONTENT_NOT_EMPTY);
        }
        // 判断同一个手机号一天发送次数
        String limitKey = Constants.LIMIT_TIMES_KEY_SUFFIX;
        if (redisService.exists(limitKey)) {
            int sendCount = (Integer) redisService.get(limitKey);
            if (sendCount >= Constants.LIMIT_COUNT) {
                serviceLogger.error("手机号" + mobile + "发送短信超过次数");
                PubFun.renderError(ErrorConsts.SEND_OUT_LIMIT);
            }
        } else {
            redisService.incr(limitKey, 0, 86400);
        }

        service.execute(new Runnable() {
            @Override
            public void run() {
                Map<String, String> conditions = new HashMap<String, String>();
                conditions.put("mobile", mobile);
                conditions.put("content", Constants.SIGNATURE + content);
                serviceLogger.info("发送短信：手机号：" + mobile + " 内容：" + Constants.SIGNATURE + content);
                String retXml = restTemplate.postForObject(StringUtil.replaceFormal(Constants.REQ_URL, conditions),
                        null, String
                                .class);
                serviceLogger.info("发送短信结果：" + retXml);
                Result ret = XStreamUtil.xmlToBean(retXml, Result.class);
                if (ret == null) {
                    serviceLogger.error("短信发送失败，返回结果：" + ret);
                } else if ("Faild".equals(ret.getReturnstatus())) {
                    serviceLogger.error("短信发送失败，返回结果：" + ret);
                } else {
                    redisService.incr(limitKey, 1);
                }
            }
        });
        return true;
    }

    /**
     * 发送验证码
     *
     * @param mobile  手机号码
     * @return
     * @throws Exception
     */
    public boolean sendVerifyCode(String mobile) throws Exception {
        String verifyCode = DataUtil.createRandomNumCode(6);
        Map<String, String> conditions = new HashMap<String, String>();
        conditions.put("verifycode", verifyCode);
        boolean sendRet = send(mobile, StringUtil.replaceFormal(smsConfig.getTemplate("general_verifycode"), conditions));
        if (sendRet) {
            redisService.set(mobile + Constants.SMSCODE__KEY_SUFFIX, verifyCode, (long) 1800);
        }
        return sendRet;
    }

    /**
     * 验证短信验证码
     *
     * @param mobile     手机号
     * @param verifyCode 输入的验证码
     * @return
     * @throws Exception
     */
    public boolean checkVerifyCode(String mobile, String verifyCode) throws Exception {
        String cacheVerifyCode = (String) redisService.get(mobile + Constants.SMSCODE__KEY_SUFFIX);
        if (StringUtil.isEmpty(verifyCode) || !verifyCode.equals(cacheVerifyCode)) {
            PubFun.renderError(ErrorConsts.VERIFYCODE_WRONG);
        }
        redisService.remove(mobile + Constants.SMSCODE__KEY_SUFFIX);
        return true;
    }

}
